#include <iostream>
#include <variant>
#include <any>
using namespace std;

class Test
{
public:
    Test(int num, string name) : m_num(num), m_name(name)
    {}
    Test(const std::initializer_list<any> &li)
    {}
    ~Test()
    {}
public:
    int m_num;
    string m_name;
};
struct PrintVisitor
{
    void operator()(int i){cout<<"int:"<<i<<'\n';}
    void operator()(char i){cout<<"char:"<<i<<'\n';}
    void operator()(const std::string &s){cout<<"str:"<<s<<'\n';}
};
struct PrintVisitorV2 
{
    void operator()(int i){cout<<"int:"<<i<<'\n';}
    void operator()(char i){cout<<"char:"<<i<<'\n';}
    void operator()(const std::string &s){cout<<"str:"<<s<<'\n';}
    void operator()(const Test &t){cout<<t.m_name<<endl;}
    void operator()(std::monostate &m){}
};

void print(variant<int,string,char> &vi)
{
    if(std::holds_alternative<int>(vi))
    {
        int num = std::get<0>(vi);
        cout << num << endl;
        cout << vi.index() << endl;
    }
    else if(std::holds_alternative<string>(vi))
    {
        string s = std::get<string>(vi);
        cout << s << endl;
    }
    else if(std::holds_alternative<char>(vi))
    {
        char ch = std::get<char>(vi);
        cout << ch << endl;
        cout << vi.index() << endl;
    }
}

int main(int argc, char **argv)
{
    variant<int,string,char> vi;
    variant<std::monostate,Test,string,int> vi2;  //第一个类型必须支持默认构造
    variant<int, string> v3 = "zhangsan";
    PrintVisitorV2 p;
    Test t(1, "zhangsan");
    vi2 = t;
    vi2.emplace<1>(1, "zhangsan");
    visit(p, vi2);
    visit([](std::any a){
        if(a.type() == typeid(string))
        {
            cout<<std::any_cast<string>(a)<<endl;
        }
        else if(a.type() == typeid(int))
        {
            cout<<std::any_cast<int>(a)<<endl;
        }
    },v3);


    string s("hello");
    //vi = 1;
    vi.emplace<0>(1);
    print(vi);
    vi = 'a';
    print(vi);
    vi = s;
    print(vi);
    //vi = string("zhangsan");

    return 0;
}
